from django.shortcuts import render

from rest_framework.views import APIView
from rest_framework.response import Response
from search.documents import CourseDocument
from elasticsearch.dsl import Q
# Create your views here.




class SearchView(APIView):
    def get(self,request):
        # 先接收参数-->1.导航栏-->2.侧边栏-->3.排序-->4.付费类型-->5.关键字
        # 顶部导航栏
        nav_name = self.request.query_params.get("nav_name")
        category_id = self.request.query_params.get("categoryId")
        sorted_num = self.request.query_params.get('sorted_num','')
        price_range = self.request.query_params.get('price_range','')
        keyword = self.request.query_params.get('keyword','').strip()


        # 分页：
        page = int(request.query_params.get('page',1))
        page_size = int(request.query_params.get('page_size',10))

        # 如果传递的参数页数小于1，那就默认页数是第一页,下面页数同理
        if page < 1:
            page = 1
        if page_size < 1:
            page_size = 10
        if page_size > 50:
            page_size = 50

        # 构建起始位：你要从第几条开始查询(看)呢？
        start = (page-1)*page_size



        # 先判断参数没有值
        if not any([nav_name,category_id,keyword]):
            return Response({
                'code':0,
                'message':'至少有一个参数'
            })

        # 设置查询对象
        search = CourseDocument.search()
        query = []

        # 查询条件列表
        if keyword:
            search = query.append(Q('multi_match',query=keyword,fields=[
                'course_name^3',
                'brief^2',
                'course_description',
                'outcomes',
                'teacher_name',
                'teacher_title',
                'category_names',
                'nav_names'
            ],type='best_fields',minimum_should_match='75%'))

        if nav_name:
            q = Q('match_phrase',nav_names=nav_name)
            query.append(q)

        if category_id:
            q = Q('match_phrase',category_ids=category_id)
            query.append(q)


        if price_range:
            if price_range in ['1','2']:
                course_type = int(price_range)
                query.append(Q('term',course_type=course_type))

        # 再做判断，验证参数是否真的存在于数据中
        # 如果：查询条件列表的长度大于1，说明需要进行组合查询
        if len(query)>1:
            search = search.query('bool',must=query)
        else:
            # 如果相反，列表中<=1，说明只有一个查询条件，那就直接取第一位(也只有一位，直接查询)
            search = search.query(query[0])


        if sorted_num:
            if sorted_num == '1':
                search = search.sort('-pub_date')
            if sorted_num == '2':
                search = search.sort('-students')
            if sorted_num == '3':
                search = search.sort('price')


        # 总条数
        total = search.count()
        print(total)
        # 这是一个切片
        search = search[start : start + page_size]

        try:
            # 执行查询
            response = search.execute()
            # 设置要返回的results的值默认为空数组,往里添加你要返回的字段
            results = []
            # 设置默认值-->用于再次过筛：参数到底是不是模型中有的字段
            is_valid = True
            for hit in response:
                if nav_name:
                    nav_names_list = [name.strip() for name in hit.nav_names.split('|')]
                    is_valid = nav_name in nav_names_list
                if category_id and is_valid:
                    category_id_list = [int(cateId.strip()) for cateId in hit.category_ids.split('|')]
                    is_valid = int(category_id) in category_id_list

                if is_valid:
                    results.append({
                        'id':hit.course_id,
                        'course_img':hit.course_img,
                        'name':hit.course_name,
                        'brief':hit.brief,
                        'teacher':{
                            'name':hit.teacher_name,
                            "title":hit.teacher_title
                        },
                        'students':hit.students,
                        'lessons':hit.lessons,
                        'course_type':hit.course_type,
                        'course_type_text': '免费' if hit.course_type == 1 else '付费',
                        'original_price':hit.original_price,
                        'price':hit.price
                    })

            # 总页数:向上取整
            total_pages = (total + page_size - 1) // page_size
            # 下一页：只要我当前页比总页数小，我就有下一页(true)
            has_next = page < total_pages
            # 上一页：只要我当前页比1大，我就有上一页(true)
            has_previous = page > 1

            print(results)

            return Response({
                'code':1,
                'message':'查询成功',
                'data':{
                    'count': total,
                    'next': has_next,
                    'previous': has_previous,
                    'results':results,
                }
            })

        except Exception as e:
            return Response({
                'code':0,
                'message':f'查询失败,错误信息为{e}'
            })











